/*
 * @Description: 
 * @version: 
 * @Author: cy
 * @Date: 2022-05-06 09:16:38
 * @LastEditors: cy
 * @LastEditTime: 2022-05-07 17:06:54
 */
/**
 * LeetCode 3:无重复字符的最长子串
 * 例如：输入"abcabcbb"
 * 输出：3
 * 思路：1.先找出所有的不包含重复字符的子串
 *       2.从中找出长度最大的那个子串，返回其长度即可
 * 步骤：1. 用双指针维护一个滑动窗口，用来剪切子串。所谓双指针就是2个
 *          变量，用来记录子串的起始位置，它们可以维护一个滑动窗口，
 *          为什么要强调滑动窗口呢？在一些视频剪切软件上，通常会有一
 *          个滑动窗口，可以拖动窗口左边的边框或者右边的边框就可以剪切
 *          视频，剪切字符串也是这样的，JS中的slice它其实也是一个滑动
 *          窗口，记录剪切的起始位置和结束位置，这就是双指针滑动窗口。
 *       2. 我们如何遍历所有的不包含重复字符的子串？首先刚开始都在第一
 *          个字符的位置，然后不断地移动右指针
 *       3. 过程中，记录所有窗口的长度，并返回最大值
 */
var lengthOfLongestSubstring = function(s) {
    // 左指针，控制左边界
    let l = 0;
    // 记录最大长度，初始值为0
    let res = 0;
    // 记录已存在的内容，并存入位置索引
    const map = new Map();
    for (let r = 0; r < s.length; r += 1) {
        if (map.has(s[r]) && map.get(s[r]) >= l) {
            // 若有重复内容，且重复的内容的下标必须在左指针后面，则左指针直接跳到重复内容的位置，长度重新计数
            l = map.get(s[r]) + 1;
        }
        // r - l：右-左，得出长度，更历史已累积的长度res相比
        res = Math.max(res, r - l + 1);
        map.set(s[r], r);
    }
    return res;
}
